import os
import subprocess
import shutil

class SlnContent():
    def __init__(self):
        pass
    
class FileFinder():
    def __init__(self, extentions):
        self.path_list = self.get_files(extentions)
        
        
        
    def type_match(self, fname, exts):
        if type(exts) == str:
            exts = [exts]
        
        for ext in exts:
            if fname.endswith(ext):
                return True
        return False

    def get_files(self, extensions):
        root = os.getcwd()
        list = []
        for dirpath, dirnames, filenames in os.walk(os.getcwd()):
            for each_file in filenames:
                if self.type_match(each_file, extensions):
                    fpath = os.path.join(dirpath, each_file)
                    print fpath
                    fname = self.get_filename(fpath)
                    list.append({'name': fname, 'path': fpath})
        return list

    def get_filename(self, file_path):
        list = file_path.split('\\')
        return list[-1].strip().replace('.sln','')
        
class SlnParser():
    def __init__(self, src):
        self.src = src #os.path.join(os.getcwd(),src)
        self.dir = os.path.dirname(self.src).replace(r'C:\Users\mz\.jenkins\jobs\xera3\workspace\iReleases\repository','$(ICONECT_WORK_HOME)')
        self.fsrc = open(src)
        self.dict = self.get_dict()

    def close(self):
        self.fsrc.close()

    def init(self):
        for line in fsrc:
            pass

    def section_start(self, line, section, identity, attr):
        start = section + '(' + identity + ') = ' + attr
        if start in line:
            return True
        else:
            return False
        
    def section_end(self, line, section):
        end = 'End' + section
        if end in line:
            return True
        else:
            return False
    def get_section(self, line, section, identity, attr):
        if self.section_start(line, section, identity, attr)
    def get_dict(self):
        proj_dict = {} 
        fsrc = self.fsrc
        for line in fsrc:
            if 'Project("{' in line:
                contents = line.split('=')
                parent_guid = contents[0].strip().strip('Project("').strip('")')
                temp = contents[1].split(',')
                values = [proj.strip().strip('"') for proj in temp]
                relative_path = values[1]
                fname = relative_path.split('\\')[-1]
                fpath = os.path.normpath( os.path.join(self.dir, relative_path))
                guid = values[2].strip()

                dependencies = []
                proj_metadata = fsrc.next()
                if 'EndProject' in proj_metadata:
                    proj_dict[guid] = {'guid':guid, 'name': fname, 'path':fpath, 'dependencies':dependencies}
                if 'ProjectSection(ProjectDependencies)' in proj_metadata:
                    section_metadata = fsrc.next()
                    while not 'EndProjectSection' in section_metadata:
                        dependency_list = section_metadata.split('=')
                        dependency = dependency_list[0].strip()
                        dependencies.append(dependency)
                        section_metadata = fsrc.next()
                    to_projend = fsrc.next()
                    while not 'EndProject' in to_projend:
                        to_projend = fsrc.next()
                    proj_dict[guid] = {'guid':guid, 'name': fname, 'path':fpath, 'dependencies':dependencies}
                 
        return proj_dict
    
    def get_proj_guid(self, line):
         contents = line.split('=')
         return contents[0].strip().strip('Project("').strip('")')
        
    def get_path(self, guid):
        for item in self.dict.values():
            if item['guid'] == guid:
                return item['path']
        return ''

    def get_dependency_name_list(self, guid):
        list = []
        if guid in self.dict:
            dependencies = self.dict[guid]['dependencies']
            for dependency in dependencies:
                list.append(self.dict[dependency]['name'])
        return list

    def get_unordered_list(self):
        list = []
        dict = self.dict
        for key in dict.keys():
            node = {'id':key, 'name':dict[key]['name']}
            node['edges'] = []
            for dep_key in dict[key]['dependencies']:
                node['edges'].append(dep_key)
            list.append(node)
        return list


class DependencyTree():
    def __init__(self, list):
        self.unordered = list

    def get_nodes_by_edge(self, edge):
        nodes = []
        for node in self.unordered:
            if edge in node['edges']:
                nodes.append(node)
        return nodes

    def has_edge(self, node):
        return len(node['edges']) > 0

    # remove node from graph
    def remove_node(self, node):
        for u in self.unordered:
            if node['id'] in u['edges']:
                u['edges'].remove( node['id'] )
        if node in self.unordered:
            self.unordered.remove( node )

    def graph_has_edge(self, list):
        for u in list:
            if self.has_edge(u):
                return True
        return False

    def topolocical_ordering(self):
        ordered = []
        noedges = []

        for node in self.unordered:
            if len(node['edges']) == 0:
                noedges.append( node )
                
        while len(noedges):
            noedge = noedges[0]
            #insert n to L
            ordered.append( noedge )
            
            #remove a node n from S
            noedges.remove( noedge )
            
            nodes = self.get_nodes_by_edge(noedge['id'])
            for item in nodes:
                self.remove_node(noedge)
                if not self.has_edge(item):
                    noedges.append( item )
                    
        if self.graph_has_edge(ordered):
            return []
        else:
            return ordered
            
def is_project_file(filename):
    for ext in ['vcxproj', 'csproj']:
        if filename.endswith(ext):
            return True
    return False        

def process_project_files(dest_dir, sln_parser, repo_home, work_home):
    src_root = os.getcwd()
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)

    fbuild = open(dest_dir + '\\..\\build.txt', 'w')

    fbuild.write('\t<ProjectToBuild Include="' + dest_proj_name + '"/>\n')

    fbuild.close()

def get_sln_content(sln_list, name):
    for sln in sln_list:
        if sln['name'] == name:
            return sln['content']
    return ''

if __name__ == '__main__':
    '''
    sln_parser = SlnParser('./xera/SuperSolution/SuperSolution.sln')
    list = sln_parser.get_unordered_list()
    
    tree = DependencyTree(list)
    ordered_list = tree.topolocical_ordering()
    print "Build order:"
    fbuild = open('.\build.txt', 'w')
    for i in ordered_list:
        print i['name']
        fbuild.write('\t<ProjectToBuild Include="' + i['name'] + '"/>\n')
    fbuild.close()
    '''

    #file_finder = FileFinder('sln')
    #fsln = open('.\slnfiles.txt')
    #results = []    
    #for line in fsln:
    sln_parser = SlnParser('superSolution.sln')
    list = sln_parser.get_unordered_list()
    tree = DependencyTree(list)
    ordered_list = tree.topolocical_ordering()
    
    #dir_list = line.strip().split('\\')
    #fname = dir_list[-1].strip().replace('.sln','')

    for item in ordered_list:
        item['path'] = sln_parser.get_path(item['id'])
    #results.append({'name':fname, 'guid':item['id'], 'content':ordered_list})
    
    #print fname + ":"
    
    #for item in ordered_list:
        #print item['name'] #+ '--------------------' + item['path']
    print "-----------------------------------------------"
    print "Total ", len(ordered_list)
'''        
    fsln.close()

    new_list = []
    sub_slns = results[0:-1]
    super_sln = results[-1]
    
    for proj in super_sln['content']:
        if '.' in proj['name']:
            new_list.append(proj['path'])
        else:
            content = get_sln_content(sub_slns, proj['name'])
            if content != '':
                for cont in content:
                    new_list.append(cont['path'])

    for kk in new_list:
        print kk
'''
